# JVM 规范完整指南 - 引言

本章节基于 [JDK 25 (2025)](https://docs.oracle.com/javase/specs/index.html) 同步发布的 JVM 规范进行翻译学习

## 1. 引言

### 1.1 背景故事

Java 编程语言是一个通用的面向对象编程语言。其语法与 C 和 C++ 类似，但省略了许多导致前两者变得复杂、混乱且不安全的特性。Java 平台最初是为了解决多平台编译问题而开发的。它的设计旨在支持多种主机架构，并允许安全地交付软件组件。为了满足这些要求，编译后的代码必须能够通过网络传输、在任何客户端上运行，并向客户端保证其运行是安全的。

互联网的普及使得这些特性变得更具吸引力。Web 浏览器使数以百万计的人能够以简单的方式浏览互联网并获取丰富的媒体内容。终于出现了一种媒介，无论您使用什么机器，也无论连接的是高速网络还是低速调制解调器，您所看到和听到的内容基本上都是一致的。

网络爱好者很快发现，浏览器所支持的 HTML 文档格式在内容表现力方面过于局限。诸如表单之类的 HTML 扩展功能，虽然在一定程度上增强了交互性，但反而更凸显了其固有的限制，同时也清楚地表明：任何浏览器都不可能内置用户所需要的全部功能。此时，（实现平台的）可扩展性成为了解决问题的关键。

HotJava 浏览器首次展示了 Java 编程语言和平台那些引人注目的特性，其实现方式是将程序（Applet）内嵌于 HTML 页面中。这些程序会随着它们所在的 HTML 页面一同被透明地下载到浏览器中。在被浏览器接受之前，这些程序会经过严格的安全检查，以确保其是安全的。与 HTML 页面一样，编译后的程序也是与网络和主机架构无关的。无论这些程序来自何处，也无论它们在被加载和运行的机器类型如何，其行为表现都完全一致。

整合了 Java 平台的 Web 浏览器，便不再局限于一套预设的功能。当用户访问包含动态内容的网页时，可以确信这些内容不会损害他们的计算机。程序员只需编写一次程序，就能在任何提供了 Java 运行时环境的机器上运行。

### 1.2 Java 虚拟机

Java 虚拟机是 Java 平台的基石。正是这一核心技术组件，赋予了 Java 硬件与操作系统的独立性、编译后代码的小巧体积，以及保护用户免受恶意程序侵害的能力。

Java 虚拟机是一台抽象的计算机。如同真实的计算机一样，它拥有自己的指令集，并且在运行时能够操作各种内存区域。采用虚拟机来实现一门编程语言是相当普遍的做法；其中最广为人知的虚拟机可能就是 UCSD Pascal 的 P-Code 机器了。

Java 虚拟机的首个原型实现由 Sun Microsystems 公司完成，它在一个类似于当代个人数字助理的手持设备上，通过软件模拟的方式实现了 Java 虚拟机指令集。而如今，Oracle 当前的实现方案则在移动设备、台式机和服务器设备上模拟 Java 虚拟机。然而，Java 虚拟机本身并不限定于任何特定的实现技术、主机硬件或主机操作系统。它并非天生就是解释执行的，同样也可以将其指令集编译成硅 CPU 的指令集来实现。它甚至还可以通过微代码形式实现，或者直接实现在硅芯片之中。

Java 虚拟机本身对 Java 编程语言一无所知，它只认识一种特定的二进制格式——类文件格式。一个类文件包含了 Java 虚拟机指令（即字节码）、符号表以及其他辅助信息。

为了确保安全，Java 虚拟机对类文件中的代码施加了严格的语法和结构约束。然而，任何其功能能够通过合法的类文件来表达的语言，都可以运行在 Java 虚拟机之上。受到这个普遍可用、与机器无关的平台吸引，其他语言的实现者可以将 Java 虚拟机作为其语言的交付载体。

类文件格式是带有版本控制的：每个类文件都会声明一个以“主版本号.次版本号”形式表示的版本号。这个版本号表明了该文件对特定 Java SE 发行版的依赖关系，并会影响 Java 虚拟机对文件内容的解释方式。

此处规范的 Java 虚拟机与 Java SE 25 兼容，并支持《Java 语言规范（Java SE 25 版）》中指定的 Java 编程语言。它支持主版本号从 45 到 69（包含两端）的类文件。

生成类文件的工具通常会采用最新的主版本号，以便利用最新的功能特性；但是，一个拥有较旧主版本号的类文件，通常可以预期在未来的 Java 虚拟机版本中继续得到支持。

作为参考，下表列出了截至 Java SE 25 的各个 Java SE 发行版所支持的类文件主版本号。第三列“最早”显示了该发行版中 Java 虚拟机所支持的最早类文件主版本号。第四列“最新”显示了该发行版中 Java 虚拟机所支持的最新类文件主版本号（对于非常早期的版本，表中显示的是 JDK 版本号而非 Java SE 发行版名称）。

**表 1.2-A. Java SE 发行版与类文件主版本号对应关系**

| Java SE 发行版 | 发布日期      | 最早支持版本 | 最新支持版本 |
| :------------- | :------------ | :----------- | :----------- |
| 1.0.2          | 1996 年 5 月  | 45           | 45           |
| 1.1            | 1997 年 2 月  | 45           | 45           |
| 1.2            | 1998 年 12 月 | 45           | 46           |
| 1.3            | 2000 年 5 月  | 45           | 47           |
| 1.4            | 2002 年 2 月  | 45           | 48           |
| 5.0            | 2004 年 9 月  | 45           | 49           |
| 6              | 2006 年 12 月 | 45           | 50           |
| 7              | 2011 年 7 月  | 45           | 51           |
| 8              | 2014 年 3 月  | 45           | 52           |
| 9              | 2017 年 9 月  | 45           | 53           |
| 10             | 2018 年 3 月  | 45           | 54           |
| 11             | 2018 年 9 月  | 45           | 55           |
| 12             | 2019 年 3 月  | 45           | 56           |
| 13             | 2019 年 9 月  | 45           | 57           |
| 14             | 2020 年 3 月  | 45           | 58           |
| 15             | 2020 年 9 月  | 45           | 59           |
| 16             | 2021 年 3 月  | 45           | 60           |
| 17             | 2021 年 9 月  | 45           | 61           |
| 18             | 2022 年 3 月  | 45           | 62           |
| 19             | 2022 年 9 月  | 45           | 63           |
| 20             | 2023 年 3 月  | 45           | 64           |
| 21             | 2023 年 9 月  | 45           | 65           |
| 22             | 2024 年 3 月  | 45           | 66           |
| 23             | 2024 年 9 月  | 45           | 67           |
| 24             | 2025 年 3 月  | 45           | 68           |
| 25             | 2025 年 9 月  | 45           | 69           |

### 1.3 JVM 规范文档的组织方式

第二章介绍了 Java 虚拟机的体系结构。

第三章介绍了如何将用 Java 编程语言编写的代码编译成 Java 虚拟机指令集。

第四章详细规定了类文件格式，这是一种独立于硬件和操作系统的二进制格式，用于表示编译后的类和接口。

第五章规定了 Java 虚拟机的启动过程，以及类和接口的加载、链接与初始化。

第六章规定了 Java 虚拟机的指令集，并按照操作码助记符的字母顺序介绍了各条指令。

第七章提供了一个按操作码数值索引的 Java 虚拟机操作码助记符表。

在《Java® 虚拟机规范（第二版）》中，第二章曾对 Java 编程语言进行了概述，其目的是为了支持 Java 虚拟机的规范说明，但其本身并非规范的一部分。而在《Java 虚拟机规范（Java SE 25 版）》中，关于 Java 编程语言的信息，请读者参阅《Java 语言规范（Java SE 25 版）》。

在《Java® 虚拟机规范（第二版）》中，第八章详细阐述了低层级的操作，用以解释 Java 虚拟机线程与共享主内存之间的交互。而在《Java 虚拟机规范（Java SE 25 版）》中，关于线程与锁的信息，请读者参阅《Java 语言规范（Java SE 25 版）》的第十七章。该第十七章反映了由 JSR 133 专家小组制定的 Java 内存模型与线程规范。

### 1.4 符号约定

在本规范中，我们多处引用了来自 Java SE 平台 API 的类和接口。当我们使用单个标识符 N 来引用一个类或接口（示例中声明的除外）时，所指的即是在 java.lang 包中名为 N 的类或接口。对于来自 java.lang 以外包的类或接口，我们使用其完全限定名称。

当我们引用在 java 包或其任何子包中声明的类或接口时，所指的即是由引导类加载器（§5.3.1）加载的该类或接口。

当我们引用名为 java 的包的子包时，所指的即是由引导类加载器所确定的该子包。

本规范中的交叉引用显示为（§x.y）。我们偶尔会通过（JLS §x.y）形式的交叉引用来引用《Java 语言规范（Java SE 25 版）》中的概念。

本规范中字体的使用约定如下：

- 等宽字体 用于表示 Java 虚拟机数据类型、异常、错误、类文件结构、Prolog 代码和 Java 代码片段。
- 斜体 用于表示 Java 虚拟机的"汇编语言"、其操作码和操作数，以及 Java 虚拟机运行时数据区中的项。它也用于引入新术语以及单纯用于强调。
- 旨在阐明本规范规范性正文的非规范性文本，会以较小字号和缩进格式呈现。

这是非规范性文本。它提供直观解释、基本原理、建议、示例等。

### 1.5 预览特性

预览特性是指：

- Java 编程语言的新特性（"预览语言特性"），或
- Java 虚拟机的新特性（"预览虚拟机特性"），或
- 在 java._ 或 javax._ 命名空间中的新模块、包、类、接口、字段、方法、构造器或枚举常量（"预览 API"）

这些特性虽然已被完整规范和实现，但并非永久性的。它们包含在特定 Java SE 平台版本的实现中，旨在通过实际使用来收集开发者的反馈；这可能导致它们在未来的 Java SE 平台版本中成为永久特性。

特定 Java SE 平台版本所定义的预览特性会在该版本的《Java SE 平台规范》中枚举列出。预览特性的规范方式如下：

- 预览语言特性 在独立的文档中规定，这些文档指明了相对于该版本《Java® 语言规范》的变更（"差异"）。当且仅当在编译时启用了预览特性，这些预览语言特性的规范才会通过引用方式并入《Java® 语言规范》，并成为其一部分。
- 预览虚拟机特性 在独立的文档中规定，这些文档指明了相对于该版本《Java® 虚拟机规范》的变更（"差异"）。当且仅当在运行时启用了预览特性，这些预览虚拟机特性的规范才会通过引用方式并入《Java® 虚拟机规范》，并成为其一部分。
- 预览 API 在该版本的《Java SE API 规范》内部进行规定。

#### 1.5.1 对使用预览特性的限制

Java SE 平台的实现在编译时和运行时均会禁用由特定版本定义的预览特性，除非用户在编译时和运行时均通过宿主系统指示启用了预览特性。实现不提供仅启用部分给定版本预览特性的方式。

一个类文件依赖于 Java SE N (N ≥ 12) 的预览特性，当且仅当满足以下条件：

- 该类文件的主版本号是表 1.2-A 中 Java SE N 所支持的最新主版本号，且
- 该类文件的次版本号为 65535。

例如，一个版本号为 66.65535 的类文件依赖于 Java SE 22 的预览特性，因为 66 是 Java SE 22 所支持的最新主版本号。

即使类文件并未使用任何预览虚拟机特性，编译器也可能需要生成依赖于特定版本预览特性的类文件。例如，一个使用了该版本预览语言特性的 Java 源文件，必须被编译成一个依赖于该版本预览特性的类文件。

在运行时，加载一个依赖于特定 Java SE 平台版本预览特性的类文件的规则在 §4.1 中规定。这样的类文件被绑定到该特定版本的 Java SE 平台，并且无法在任何其他版本上加载（即使启用了预览特性），因为它所依赖的预览特性在其他版本中可能不同或缺失。

#### 1.5.1 当前预览版虚拟机特性

Java SE 25 未定义任何预览版虚拟机特性。

### 1.6 反馈

我们诚邀读者将《Java® 虚拟机规范》中的技术性错误和模糊之处报告至jls-jvms-spec-comments@openjdk.org

关于 javac（Java 编程语言的参考编译器）生成和操作类文件的问题，可发送至 compiler-dev@openjdk.org
